package handler

import (
	"context"
	"fmt"
	"go-likaladi-shop/common/base_global"
	"go-likaladi-shop/common/base_model"
	"go-likaladi-shop/common/base_util"
	"google.golang.org/protobuf/types/known/emptypb"
	"lw-shop/goods_service/model"
	"lw-shop/goods_service/proto"
)

func (s *GoodsService) BrandList(ctx context.Context, req *proto.BrandFilterRequest) (*proto.BrandListResponse, error) {
	brandListResponse := proto.BrandListResponse{}
	var brands []model.Brands
	//select * from xx_table limit index, size
	result := base_global.DB.Scopes(base_util.Paginate(int(req.Pages), int(req.PagePerNums))).Find(&brands)
	if result.Error != nil {
		return nil, base_util.GrpcError(result.Error)
	}

	var total int64
	//select count(1) from xx_table
	base_global.DB.Model(&model.Brands{}).Count(&total)
	brandListResponse.Total = int32(total)

	var dataResults []*proto.BrandInfoResponse

	for _, brand := range brands {
		dataResults = append(dataResults, &proto.BrandInfoResponse{
			Id:   brand.ID,
			Name: brand.Name,
			Logo: brand.Logo,
		})
	}
	brandListResponse.Data = dataResults
	return &brandListResponse, nil
}

func (s *GoodsService) CreateBrand(ctx context.Context, req *proto.BrandRequest) (*proto.BrandResponse, error) {
	if req.Name == "" {
		return nil, base_util.LogicError("品牌名称不能为空")
	}

	var brand1 model.Brands
	//select * from xx_table where name = xx limit 1 ; RowsAffected表示数量
	if result := base_global.DB.Where(&model.Brands{Name: req.Name}).First(&brand1); result.RowsAffected == 1 {
		return nil, base_util.LogicError("品牌已存在")
	}

	//创建db实体
	brand := &model.Brands{
		Name: req.Name,
		Logo: req.Logo,
	}
	base_global.DB.Save(brand)
	return &proto.BrandResponse{Id: brand.ID}, nil
}

func (s *GoodsService) UpdateBrand(ctx context.Context, req *proto.BrandRequest) (*emptypb.Empty, error) {
	if req.Name == "" || req.Id == 0 {
		return nil, base_util.LogicError("id或者品牌名称不能为空")
	}

	var brands []model.Brands

	//SELECT * FROM `brands` WHERE (id = xx or name = 'xx') AND `brands`.`deleted_at` IS NULL
	db := base_global.DB.Model(&model.Brands{})
	if req.Name != "" && req.Id != 0 {
		db = db.Where("id = ? or name = ?", req.Id, req.Name)
	}
	if result := db.Find(&brands); result.Error != nil {
		return nil, base_util.GrpcError(result.Error)
	}

	if err := updateValidate(brands, req); err != nil {
		return nil, err
	}

	//创建db实体
	brand := &model.Brands{
		BaseModel: base_model.BaseModel{ID: req.Id},
	}

	if req.Name != "" {
		brand.Name = req.Name
	}
	if req.Logo != "" {
		brand.Logo = req.Logo
	}
	base_global.DB.Save(&brand)
	return &emptypb.Empty{}, nil
}

type BrandResult struct {
	ID   int32
	Name string
	Logo string
}

func (s *GoodsService) UpdateBrandForSql(ctx context.Context, req *proto.BrandRequest) (*emptypb.Empty, error) {
	if req.Name == "" || req.Id == 0 {
		return nil, base_util.LogicError("id或者品牌名称不能为空")
	}

	var results []BrandResult

	db := base_global.DB.
		Select("t1.id, t1.name, t1.logo").
		Table("brands t1").
		Where("t1.deleted_at IS NULL")

	if req.Name != "" && req.Id != 0 {
		db = db.Where("t1.id = ? or t1.name = ?", req.Id, req.Name)
	}
	if req.Logo != "" {
		db = db.Where("t1.logo = ? ", req.Logo)
	}

	if err := db.Scan(&results).Error; err != nil {
		return nil, base_util.GrpcError(err)
	}
	for _, result := range results {
		fmt.Println(result)
	}
	return &emptypb.Empty{}, nil
}

func (s *GoodsService) DeleteBrand(ctc context.Context, req *proto.BrandRequest) (*emptypb.Empty, error) {
	//delete from xx_table where id = xx
	result := base_global.DB.Delete(&model.Brands{}, req.Id)
	if result.Error != nil {
		return nil, base_util.GrpcError(result.Error)
	}
	if result.RowsAffected == 0 {
		return nil, base_util.LogicError("品牌不存在")
	}
	return &emptypb.Empty{}, nil
}

func updateValidate(brands []model.Brands, req *proto.BrandRequest) error {
	idTemp := false
	nameTemp := false
	for _, brand := range brands {
		if brand.ID == req.Id {
			idTemp = true
		}
		if brand.Name == req.Name {
			nameTemp = true
		}
	}

	if !idTemp {
		return base_util.LogicError("无匹配的品牌记录")
	}
	if nameTemp {
		return base_util.LogicError("品牌名称已存在")
	}
	return nil
}

// QueryBrandsByIds 根据传入的品牌ID列表，批量查询品牌信息。
// 若传入空的ID列表，则直接返回空切片，不执行数据库查询。
func QueryBrandsByIds(brandIds []int32) ([]*proto.BrandInfoResponse, error) {
	// 判断ID列表是否为空，若为空直接返回空结果，避免不必要的数据库访问
	if len(brandIds) == 0 {
		return []*proto.BrandInfoResponse{}, nil
	}

	// 定义用于存储数据库查询结果的实体切片
	var brands []model.Brands

	// 使用 GORM 的 IN 查询语法，根据 ID 列表批量查询品牌信息
	if err := base_global.DB.
		Where("id IN ?", brandIds).
		Find(&brands).Error; err != nil {
		// 查询出错时，使用封装的 gRPC 错误处理函数返回错误
		return nil, base_util.GrpcError(err)
	}

	// 定义结果切片，将数据库实体转换为 proto 响应结构
	var result []*proto.BrandInfoResponse
	for _, brand := range brands {
		result = append(result, &proto.BrandInfoResponse{
			Id:   brand.ID,   // 品牌ID
			Name: brand.Name, // 品牌名称
			Logo: brand.Logo, // 品牌LOGO
		})
	}

	// 返回转换后的结果集和nil错误
	return result, nil
}

func BrandDBMap(brandIds []int32) (map[int32]*proto.BrandInfoResponse, error) {
	brands, err := QueryBrandsByIds(brandIds)
	if err != nil {
		return nil, err
	}
	brandMap := base_util.SliceToMap(brands, func(obj *proto.BrandInfoResponse) int32 {
		return obj.Id
	})
	return brandMap, nil
}
